package com.xiaoxie.web.system;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.property.ColumnWidthProperty;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.github.pagehelper.PageInfo;
import com.xiaoxie.common.domain.ExportExcelColumnConfig;
import com.xiaoxie.common.excel.CustomColumnWidthStyleStrategy;
import com.xiaoxie.common.union.R;
import com.xiaoxie.common.utils.ExportUtils;
import com.xiaoxie.system.domain.DictType;
import com.xiaoxie.system.service.DictService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/system/dict")
@Tag(name = "数据字典管理",description = "数据字典管理")
public class DictController {

    @Resource
    private DictService dictService;

    @GetMapping("/hasType")
    @Operation(summary = "查询数据字典项数量")
    public R dictTypeHasType(@RequestParam("type") String type) {
        boolean b = dictService.dictTypeHasType(type);
        return R.ok(b);
    }

    @Operation(summary = "根据id查询数据字典")
    @GetMapping("/{id}")
    public R getDictTypeById(@PathVariable("id") Integer id) {
        DictType dictType = dictService.getDictTypeById(id);
        return R.ok(dictType);
    }

    @PostMapping("/add")
    @Operation(summary = "添加数据字典项")
    public R addDictType(@RequestBody DictType dictType) {
        dictService.addDictType(dictType);
        return R.ok("添加成功");
    }

    @Operation(summary = "更新数据字典项")
    @PutMapping("/update")
    public R updateDictType(@RequestBody DictType dictType) {
        dictService.updateDictType(dictType);
        return R.ok("修改成功");
    }

    @Operation(summary = "删除数据字典项")
    @DeleteMapping("/delete/{id}")
    public R deleteDictType(@PathVariable("id") Integer id) {
        dictService.deleteDictTypeById(id);
        return R.ok("删除成功");
    }

    @Operation(summary = "分页查询数据字典项")
    @GetMapping("/list")
    public R selectDictTypeByPage(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                  DictType dictType) {
        PageInfo<DictType> pageInfo = dictService.selectDictTypeByPage(pageNum, dictType);
        return R.ok(pageInfo);
    }

    @Operation(summary = "获取所有数据字典项")
    @GetMapping("/all")
    public R getAllDictType() {
        List<DictType> all = dictService.getAllDictTypes();
        return R.ok(all);
    }

    @Operation(summary = "批量删除字典项")
    @DeleteMapping("/batchDelete")
    public R batchDeleteDictType(@RequestParam("ids") String ids) {
        List<Integer> idList = Arrays.stream(ids.split(","))
                .map(Integer::parseInt)
                .toList();
        dictService.batchDeleteDictType(idList);
        return R.ok("删除成功");
    }

    @Operation(summary = "导出Excel文件")
    @GetMapping("/export")
    public ResponseEntity<InputStreamResource> exportDictType(DictType dictType) throws IOException {
        log.info(dictType.getType());
        // 生成临时文件
        File tempFile = File.createTempFile("dictType", ".xlsx");
        tempFile.deleteOnExit();

        try(FileOutputStream fos = new FileOutputStream(tempFile)) {
            // 获得数据
            List<Map<String,Object>> data = dictService.getDictTypeAndValueForExcel(dictType);
            // 定义表头信息
            List<ExportExcelColumnConfig> headers = Arrays.asList(
                    new ExportExcelColumnConfig(1,"type","字典项类型",30),
                    new ExportExcelColumnConfig(2,"type_desc","字典项描述",50),
                    new ExportExcelColumnConfig(3,"value","字典项值",30),
                    new ExportExcelColumnConfig(4,"value_desc","字典项值描述",50)
            );
            // 获取表头与表体数据
            List<List<String>> header = ExportUtils.getHeaders(headers);
            List<List<Object>> dataList = ExportUtils.getValues(headers, data);

            int[] columnWidths = ExportUtils.getHeaderWidth(headers);

            // 创建ColumnWidthStyleStyle对象，用来设置Excel文件的列宽
            CustomColumnWidthStyleStrategy columnWidthStyleStrategy = new CustomColumnWidthStyleStrategy(columnWidths);
            EasyExcel.write(fos)
                    .head(header)
                    .registerWriteHandler(columnWidthStyleStrategy)
                    .sheet("数据字典")
                    .doWrite(dataList);

            // doFill是用来进行Excel文件的填充的，我们这里没有给定Excel的模板，没有办法进去填充
            /*
            EasyExcel.write(fos)
                    .withTemplate(inpStream)
                    .sheet()
                    .doFill(data);
                   */

        }
        // 设置响应头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        String fileName = URLEncoder.encode("数据字典.xlsx", StandardCharsets.UTF_8);
        httpHeaders.setContentDisposition(ContentDisposition.attachment().filename(fileName).build());
        httpHeaders.setAccessControlExposeHeaders(List.of("Content-Disposition"));
        // 返回响应
        InputStreamResource resource = new InputStreamResource(new FileInputStream(tempFile));
        return ResponseEntity.ok()
                .headers(httpHeaders)
                .body(resource);
    }
}
